home *** CD-ROM | disk | FTP | other *** search
/ 3D Games - Real-time Rend…ng & Software Technology / 3D Games - Real-time Rendering & Software Technology.iso / flysdk / lib / flyEngine / flyMesh.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-21  |  16.3 KB  |  773 lines

  1. #include "../Fly3D.h"
  2.  
  3. #define INCHE_TO_DECIMETER 0.254f
  4.  
  5. class import_3ds_mesh : private import3ds
  6. {
  7.     mesh *obj;
  8.     int v,f,t,basev,basef;
  9.     float *tx;
  10.  
  11.     void object3d(char *name,int nv,int nf,int ntc,float *local_axis);
  12.     void vertex3(float *vec);
  13.     void text_coord(float *uv);
  14.     void face3(unsigned short *fa);
  15.     void face_material(material *mat,int nf,unsigned short *faces);
  16. public:
  17.     import_3ds_mesh(char *file,mesh *m);
  18. };
  19.  
  20. void mesh::reset()
  21. {
  22.     if (vert)
  23.         delete vert;
  24.     if (vertnorm)
  25.         delete vertnorm;
  26.     if (faces)
  27.         delete faces;
  28.     if (localfaces)
  29.         delete localfaces;
  30.     if (edges)
  31.         delete edges;
  32.     vert=0;
  33.     vertnorm=0;
  34.     faces=0;
  35.     nv=0;
  36.     nf=0;
  37.     localfaces=0;
  38.     edges=0;
  39.     nedges=0;
  40.     color.vec(0.0f,0.0f,0.0f);
  41. }
  42.  
  43. mesh *mesh::clone()
  44. {
  45.     mesh *m=new mesh;
  46.     *m=*this;
  47.     
  48.     m->vert=new vector[nv];
  49.     m->vertnorm=new vector[nv];
  50.     m->edges=new int[nedges*4];
  51.     memcpy(m->vert,vert,sizeof(vector)*nv);
  52.     memcpy(m->vertnorm,vertnorm,sizeof(vector)*nv);
  53.     memcpy(m->edges,edges,sizeof(int)*nedges*4);
  54.  
  55.     m->faces=new face *[nf];
  56.     m->localfaces=new face[nf];
  57.     for( int i=0;i<nf;i++ )
  58.     {
  59.         m->faces[i]=&m->localfaces[i];
  60.         m->localfaces[i]=localfaces[i];
  61.         m->localfaces[i].vert[0]=&m->vert[localfaces[i].vert[0]-vert];
  62.         m->localfaces[i].vert[1]=&m->vert[localfaces[i].vert[1]-vert];
  63.         m->localfaces[i].vert[2]=&m->vert[localfaces[i].vert[2]-vert];
  64.     }
  65.     return m;
  66. }
  67.  
  68. int mesh::get_edge(int v1,int v2)
  69. {
  70.     int i,j;
  71.     for( i=j=0;i<nedges;i++,j+=4 )
  72.         if ((v1==edges[j] && v2==edges[j+1]) ||
  73.             (v1==edges[j+1] && v2==edges[j]))
  74.             return i;
  75.     return -1;
  76. }
  77.  
  78. void mesh::compute_normals(int flag)
  79. {
  80.     int i,j;
  81.     vector v1,v2;
  82.  
  83.     if (flag&MESH_IMPLODE)
  84.         implode();
  85.  
  86.     if (flag&MESH_FACENORM)
  87.     for( i=0;i<nf;i++ )
  88.     {
  89.         v1=*faces[i]->vert[1]-*faces[i]->vert[0];
  90.         v2=*faces[i]->vert[2]-*faces[i]->vert[0];
  91.         faces[i]->normal.cross(v1,v2);
  92.         faces[i]->normal.normalize();
  93.         faces[i]->d0=-vec_dot(faces[i]->normal,*faces[i]->vert[0]);
  94.         for( j=0;j<3;j++ )
  95.         {
  96.             faces[i]->edgenormal[j].cross(
  97.                 *faces[i]->vert[(j+1)%3]-*faces[i]->vert[j],
  98.                 faces[i]->normal);
  99.             faces[i]->edgenormal[j].normalize();
  100.         }
  101.     }
  102.  
  103.     if ((flag&MESH_VERTNORM) && vert)
  104.     {
  105.     if (vertnorm)
  106.         delete vertnorm;
  107.     vertnorm=new vector[nv];
  108.     memset(vertnorm,0,sizeof(vector)*nv);
  109.     for( j=0;j<nf;j++ )
  110.     {
  111.         vertnorm[faces[j]->vert[0]-vert]+=faces[j]->normal;
  112.         vertnorm[faces[j]->vert[1]-vert]+=faces[j]->normal;
  113.         vertnorm[faces[j]->vert[2]-vert]+=faces[j]->normal;
  114.     }
  115.     for( j=0;j<nv;j++ )
  116.         vertnorm[j].normalize();
  117.     for( i=0;i<nf;i++ )
  118.         for( j=0;j<3;j++ )
  119.             faces[i]->vertnormal[j]=vertnorm[faces[i]->vert[j]-vert];
  120.     }
  121.  
  122.     if (flag&MESH_BBOX)
  123.     {
  124.     bbox.reset();
  125.     for( i=0;i<nf;i++ )
  126.         for( j=0;j<3;j++ )
  127.             bbox.add_point(*faces[i]->vert[j]);
  128.     }
  129.  
  130.     if (flag&MESH_EDGES)
  131.     {
  132.         if (edges)
  133.             delete edges;
  134.         edges=new int[nf*3*4];
  135.         nedges=0;
  136.         int e,i1,i2;
  137.         // for each face
  138.         for( i=0;i<nf;i++ )
  139.             // for each face edge
  140.             for( j=0;j<3;j++ )
  141.             {
  142.                 i1=faces[i]->vert[j]-vert;
  143.                 i2=faces[i]->vert[(j+1)%3]-vert;
  144.                 e=get_edge(i1,i2);
  145.                 // if edge is not in edge list
  146.                 if (e==-1)
  147.                 {
  148.                     // add a new edge to the list
  149.                     edges[nedges*4]=i1;
  150.                     edges[nedges*4+1]=i2;
  151.                     edges[nedges*4+2]=i;
  152.                     edges[nedges*4+3]=-1;
  153.                     nedges++;
  154.                 }
  155.                 else 
  156.                 if ((faces[i]->color-faces[edges[e*4+2]]->color).length()<0.1f)
  157.                     edges[e*4+3]=i;
  158.             }
  159.     }
  160. }
  161.  
  162. int mesh::load_3ds(char *name)
  163. {
  164.     import_3ds_mesh i(name,this);
  165.  
  166.     compute_normals(MESH_IMPLODE|MESH_FACENORM|MESH_VERTNORM|MESH_BBOX);
  167.  
  168.     return nf>0;
  169. }
  170.  
  171. import_3ds_mesh::import_3ds_mesh(char *file,mesh *m)
  172. {
  173.     obj=m;
  174.     basev=0;
  175.     basef=0;
  176.     tx=0;
  177.     t=0;
  178.     if (obj && file && file[0])
  179.         import(file,INCHE_TO_DECIMETER);
  180.     int i;
  181.     for( i=0;i<obj->nf;i++ )
  182.     {
  183.         obj->faces[i]->vert[0]=&obj->vert[(int)obj->faces[i]->vert[0]];
  184.         obj->faces[i]->vert[1]=&obj->vert[(int)obj->faces[i]->vert[1]];
  185.         obj->faces[i]->vert[2]=&obj->vert[(int)obj->faces[i]->vert[2]];
  186.     }
  187.     if (tx)    delete tx;
  188. }
  189.  
  190. void import_3ds_mesh::object3d(char *name,int nv,int nf,int ntc,float *local_axis)
  191. {
  192.     v=f=0;
  193.     
  194.     basev=obj->nv;
  195.     basef=obj->nf;
  196.  
  197.     obj->pivotpos.x=local_axis[9];
  198.     obj->pivotpos.y=local_axis[10];
  199.     obj->pivotpos.z=local_axis[11];
  200.  
  201.     face *tf;
  202.     tf=new face[nf+obj->nf];
  203.     if (obj->localfaces)
  204.     {
  205.         memcpy(tf,obj->localfaces,sizeof(face)*obj->nf);
  206.         delete obj->localfaces;
  207.     }
  208.     obj->localfaces=tf;
  209.  
  210.     vector *tv=new vector[nv+obj->nv];
  211.     if (obj->vert)
  212.     {
  213.         memcpy(tv,obj->vert,sizeof(vector)*obj->nv);
  214.         delete obj->vert;
  215.     }
  216.     obj->vert=tv;
  217.  
  218.     float *ttx=new float[2*(obj->nv+nv)];
  219.     if (tx)
  220.     {
  221.         memcpy(ttx,tx,sizeof(float)*2*obj->nv);
  222.         delete tx;
  223.     }
  224.     tx=ttx;
  225.  
  226.     obj->nv+=nv;
  227.     obj->nf+=nf;
  228.  
  229.     if (obj->faces)
  230.         delete obj->faces;
  231.     obj->faces=new face *[obj->nf];
  232.     int i;
  233.     for( i=0;i<obj->nf;i++ )
  234.         obj->faces[i]=&obj->localfaces[i];
  235. }
  236.  
  237. void import_3ds_mesh::vertex3(float *vec)
  238. {
  239.     obj->vert[basev+v].x=vec[0];
  240.     obj->vert[basev+v].y=vec[1];
  241.     obj->vert[basev+v].z=vec[2];
  242.     v++;
  243. }
  244.  
  245. void import_3ds_mesh::text_coord(float *uv)
  246. {
  247.     tx[t*2]=uv[0];
  248.     tx[t*2+1]=uv[1];
  249.     t++;
  250. }
  251.  
  252. void import_3ds_mesh::face3(unsigned short *fa)
  253. {
  254.     obj->faces[basef+f]->vert[0]=((vector *)(fa[0]+basev));
  255.     obj->faces[basef+f]->vert[1]=((vector *)(fa[1]+basev));
  256.     obj->faces[basef+f]->vert[2]=((vector *)(fa[2]+basev));
  257.     obj->faces[basef+f]->uv[0][0]=tx[(fa[0]+basev)*2];
  258.     obj->faces[basef+f]->uv[0][1]=tx[(fa[0]+basev)*2+1];
  259.     obj->faces[basef+f]->uv[1][0]=tx[(fa[1]+basev)*2];
  260.     obj->faces[basef+f]->uv[1][1]=tx[(fa[1]+basev)*2+1];
  261.     obj->faces[basef+f]->uv[2][0]=tx[(fa[2]+basev)*2];
  262.     obj->faces[basef+f]->uv[2][1]=tx[(fa[2]+basev)*2+1];
  263.     obj->faces[basef+f]->texpic=-1;
  264.     obj->faces[basef+f]->lm=-1;
  265.     obj->faces[basef+f]->color.vec(0.5f,0.5f,0.5f,0.5f);
  266.     obj->faces[basef+f]->emmradius=0.0f;
  267.     obj->faces[basef+f]->lastdraw=0;
  268.     f++;
  269. }
  270.  
  271. void import_3ds_mesh::face_material(material *mat,int nf,unsigned short *faces)
  272. {
  273.     int i,pic;
  274.  
  275.     if (mat->map_texture1.filename[0])
  276.         pic=flyengine->get_picture(mat->map_texture1.filename);
  277.     else pic=-1;
  278.  
  279.     for( i=0;i<nf;i++ )
  280.         {
  281.         obj->faces[faces[i]+basef]->texpic=pic;
  282.         obj->faces[faces[i]+basef]->color.x=mat->diffuse[0];
  283.         obj->faces[faces[i]+basef]->color.y=mat->diffuse[1];
  284.         obj->faces[faces[i]+basef]->color.z=mat->diffuse[2];
  285.         obj->faces[faces[i]+basef]->color.w=1-mat->transparency;
  286.         }
  287. }
  288.  
  289. int face::ray_intersect(vector& ro,vector& rd,vector& ip,float& dist,float rad)
  290. {
  291.     if (rad==0.0f)
  292.     {
  293.         float x=vec_dot(normal,rd);
  294.         if (x>-SMALL || *((int *)&color.w)==0)
  295.             return 0;
  296.         dist=(vec_dot(normal,*vert[0])-vec_dot(normal,ro))/x;
  297.         if (dist<0)
  298.             return 0;
  299.  
  300.         ip.x=ro.x+rd.x*dist;
  301.         ip.y=ro.y+rd.y*dist;
  302.         ip.z=ro.z+rd.z*dist;
  303.  
  304.         int i;
  305.         for( i=0;i<3;i++ )
  306.             if ((ip.x-vert[i]->x)*edgenormal[i].x+
  307.                 (ip.y-vert[i]->y)*edgenormal[i].y+
  308.                 (ip.z-vert[i]->z)*edgenormal[i].z > 0)
  309.                 return 0;
  310.  
  311.         return 1;
  312.     }
  313.     else
  314.     {
  315.         static vector v[3],n;
  316.  
  317.         v[0].x=vert[0]->x+vertnormal[0].x*rad;
  318.         v[0].y=vert[0]->y+vertnormal[0].y*rad;
  319.         v[0].z=vert[0]->z+vertnormal[0].z*rad;
  320.         
  321.         v[1].x=vert[1]->x+vertnormal[1].x*rad;
  322.         v[1].y=vert[1]->y+vertnormal[1].y*rad;
  323.         v[1].z=vert[1]->z+vertnormal[1].z*rad;
  324.         
  325.         v[2].x=vert[2]->x+vertnormal[2].x*rad;
  326.         v[2].y=vert[2]->y+vertnormal[2].y*rad;
  327.         v[2].z=vert[2]->z+vertnormal[2].z*rad;
  328.  
  329.         n.cross(v[1]-v[0],v[2]-v[0]);
  330.         n.normalize();
  331.     
  332.         float x=vec_dot(n,rd);
  333.         if (x>-SMALL || *((int *)&color.w)==0)
  334.             return 0;
  335.         dist=(vec_dot(n,v[0])-vec_dot(n,ro))/x;
  336.         if (dist<0)
  337.             return 0;
  338.  
  339.         ip.x=ro.x+rd.x*dist;
  340.         ip.y=ro.y+rd.y*dist;
  341.         ip.z=ro.z+rd.z*dist;
  342.  
  343.         int i,j,crossings=0,u0,u1;
  344.         n.x=(float)fabs(n.x);
  345.         n.y=(float)fabs(n.y);
  346.         n.z=(float)fabs(n.z);
  347.         if (n.x>n.y && n.x>n.z)
  348.             { u0=1; u1=2; }
  349.         else 
  350.         if (n.y>n.x && n.y>n.z)
  351.             { u0=0; u1=2; }
  352.         else 
  353.             { u0=0; u1=1; }
  354.  
  355.         v[0][u0]-=ip[u0];
  356.         v[1][u0]-=ip[u0];
  357.         v[2][u0]-=ip[u0];
  358.         v[0][u1]-=ip[u1];
  359.         v[1][u1]-=ip[u1];
  360.         v[2][u1]-=ip[u1];
  361.         
  362.         for( i=0; i<3; i++ )
  363.             {
  364.             j=(i+1) % 3;
  365.             if(((v[i][u1]<-SMALL) && (v[j][u1]>=0)) || ((v[j][u1]<-SMALL) && (v[i][u1]>=0.0)))
  366.                 if((v[i][u0]>=0.0) && (v[j][u0]>=0.0))
  367.                     ++crossings;
  368.                 else
  369.                     if((v[i][u0]>=0.0) || (v[j][u0]>=0.0))
  370.                         if((v[i][u0]-v[i][u1]*(v[j][u0]-v[i][u0])/(v[j][u1]-v[i][u1]))>SMALL)
  371.                             ++crossings;
  372.             }
  373.         if((crossings%2)==0)
  374.             return 0;
  375.         else
  376.             return 1;
  377.     }
  378. }
  379.  
  380. int mesh::ray_intersect(vector& ro,vector& rd,vector& ip,float& dist,float rad)
  381. {
  382.     static vector tmp_ip;
  383.     static float tmp_dist;
  384.     int i,f=-1;
  385.     dist=BIG;
  386.  
  387.     for( i=0;i<nf;i++ )
  388.         if (faces[i]->ray_intersect(ro,rd,tmp_ip,tmp_dist,rad))
  389.             if (tmp_dist<dist)
  390.             {
  391.             dist=tmp_dist;
  392.             ip=tmp_ip;
  393.             f=i;
  394.             }
  395.  
  396.     return f;
  397. }
  398.  
  399. int mesh::ray_intersect_test(vector& ro,vector& rd,float rad)
  400. {
  401.     static vector tmp_ip;
  402.     static float tmp_dist;
  403.     int i;
  404.  
  405.     for( i=0;i<nf;i++ )
  406.         if (faces[i]->ray_intersect(ro,rd,tmp_ip,tmp_dist,rad))
  407.             if (tmp_dist<0.99f)
  408.                 return 1;
  409.     return 0;
  410. }
  411.  
  412. void face::inverse_map(vector& p, float& u, float& v)
  413. {
  414.     vector v1=*vert[1]-*vert[0],
  415.         v2=*vert[2]-*vert[0],
  416.         ip=p-*vert[0];
  417.  
  418.     float det;
  419.  
  420.     det=v1.x*v2.y-v1.y*v2.x;
  421.     if(det!=0.0f)
  422.     {
  423.         u=(ip.x*v2.y-ip.y*v2.x)/det;
  424.         v=(v1.x*ip.y-v1.y*ip.x)/det;
  425.         return;
  426.     }
  427.  
  428.     det=v1.x*v2.z-v1.z*v2.x;
  429.     if(det!=0.0f)
  430.     {
  431.         u=(ip.x*v2.z-ip.z*v2.x)/det;
  432.         v=(v1.x*ip.z-v1.z*ip.x)/det;
  433.         return;
  434.     }
  435.  
  436.     det=v1.y*v2.z-v1.z*v2.y;
  437.     u=(ip.y*v2.z-ip.z*v2.y)/det;
  438.     v=(v1.y*ip.z-v1.z*ip.y)/det;
  439. }
  440.  
  441. void face::forward_map(float& u,float& v,vector& p)
  442. {
  443.     p.x=vert[0]->x+
  444.         (vert[1]->x-vert[0]->x)*u+
  445.         (vert[2]->x-vert[0]->x)*v;
  446.     p.y=vert[0]->y+
  447.         (vert[1]->y-vert[0]->y)*u+
  448.         (vert[2]->y-vert[0]->y)*v;
  449.     p.z=vert[0]->z+
  450.         (vert[1]->z-vert[0]->z)*u+
  451.         (vert[2]->z-vert[0]->z)*v;
  452. }
  453.  
  454. void mesh::illum_faces(vector& ip,float d_max,vector& c,int shadows)
  455. {
  456.     if (lastdraw<flyengine->cur_frame_base || (flyengine->mapmode&MAPPING_LIGHTMAP)==0)
  457.         return;
  458.  
  459.     light_map *lm;
  460.     int i;
  461.  
  462.     for( i=0;i<nf;i++ )
  463.         if(faces[i]->lm!=-1)
  464.             {
  465.             lm=flyengine->lm[faces[i]->lm];
  466.             if (lm->lastupdate!=flyengine->cur_step)
  467.                 if (fabs(faces[i]->distance(ip))<d_max)
  468.                     {
  469.                     lm->illum(ip,c,d_max,shadows);
  470.                     lm->lastupdate=flyengine->cur_step;
  471.                     }
  472.             }
  473. }
  474.  
  475. mesh *static_mesh::ray_intersect(vector& ro,vector& rd,vector& ip,float& dist,int &facenum,float rad)
  476. {
  477.     if (objmesh)
  478.     {
  479.         facenum=objmesh->ray_intersect(ro,rd,ip,dist,rad);
  480.         if (facenum!=-1)
  481.             return objmesh;
  482.     }
  483.     return 0;
  484. }
  485.  
  486. int static_mesh::ray_intersect_test(vector& ro,vector& rd,float rad)
  487. {
  488.     if (objmesh)
  489.         if (objmesh->ray_intersect_test(ro,rd,rad))
  490.             return 1;
  491.     return 0;
  492. }
  493.  
  494. int static_mesh::message(vector& p,float rad,int msg,int param,void *data)
  495. {
  496.     if (msg==FLYOBJM_ILLUM)
  497.         if (objmesh)
  498.             objmesh->illum_faces(p,rad,*((vector *)data),param);
  499.     return 0;
  500. }
  501.  
  502. void anim_mesh::reset()
  503. {
  504.     if (ao_vert) delete ao_vert;
  505.     if (ao_bbox) delete ao_bbox;
  506.     if (stripfancount) delete stripfancount;
  507.     if (stripfanvert) delete stripfanvert;
  508.     if (vertdata) delete vertdata;
  509.     nframes=0;
  510.     ao_vert=0;
  511.     ao_bbox=0;
  512.     nstripfan=0;
  513.     nstripfanvert=0;
  514.     stripfancount=0;
  515.     stripfanvert=0;
  516.     vertdata=0;
  517. }
  518.  
  519. void anim_mesh::compute_bbox()
  520. {
  521.     int i,j,k=nv;
  522.     vector *v=ao_bbox;
  523.     for( i=0;i<nframes;i++ )
  524.     {
  525.         v[0].vec(BIG,BIG,BIG);
  526.         v[1].vec(-BIG,-BIG,-BIG);
  527.         for( j=k-nv;j<k;j++ )
  528.         {
  529.             if (ao_vert[j].x<v[0].x)
  530.                 v[0].x=ao_vert[j].x;
  531.             if (ao_vert[j].y<v[0].y)
  532.                 v[0].y=ao_vert[j].y;
  533.             if (ao_vert[j].z<v[0].z)
  534.                 v[0].z=ao_vert[j].z;
  535.  
  536.             if (ao_vert[j].x>v[1].x)
  537.                 v[1].x=ao_vert[j].x;
  538.             if (ao_vert[j].y>v[1].y)
  539.                 v[1].y=ao_vert[j].y;
  540.             if (ao_vert[j].z>v[1].z)
  541.                 v[1].z=ao_vert[j].z;
  542.         }
  543.         v+=2;
  544.         k+=nv;
  545.     }
  546. }
  547.  
  548. int anim_mesh::load_fao(char *name)
  549. {
  550.     reset();
  551.     fly_pak fp;
  552.     if (fp.open(name))
  553.         {
  554.         int i;
  555.         char skin[256];
  556.         float *ao_uv;
  557.         short *ao_face;
  558.  
  559.         fp.read(&i,sizeof(int));
  560.         if (i!=9171)
  561.             {
  562.             fp.close();
  563.             return 0;
  564.             }
  565.  
  566.         fp.read(&nf,sizeof(int));
  567.         fp.read(&nv,sizeof(int));
  568.         fp.read(&nframes,sizeof(int));
  569.         fp.read(&pivotpos,3*sizeof(float));
  570.         fp.read(skin,64);
  571.  
  572.         ao_vert=new vector[nv*nframes];
  573.         ao_bbox=new vector[2*nframes];
  574.         ao_uv=new float[6*nf];
  575.         ao_face=new short[3*nf];
  576.  
  577.         fp.read(ao_face,nf*sizeof(short)*3);
  578.         fp.read(ao_uv,nf*sizeof(float)*6);
  579.         for( i=0;i<nv*nframes;i++ )
  580.             fp.read(&ao_vert[i],sizeof(float)*3);
  581.  
  582.         fp.read(&nstripfan,sizeof(int));
  583.         if (nstripfan)
  584.         {
  585.         stripfancount=new int[nstripfan];
  586.         fp.read(stripfancount,nstripfan*sizeof(int));
  587.         fp.read(&nstripfanvert,sizeof(int));
  588.         stripfanvert=new int[nstripfanvert];
  589.         vertdata=new vertex[nstripfanvert];
  590.         for( i=0;i<nstripfanvert;i++ )
  591.             {
  592.             fp.read(&vertdata[i].u,sizeof(float));
  593.             fp.read(&vertdata[i].v,sizeof(float));
  594.             fp.read(&stripfanvert[i],sizeof(int));
  595.             }
  596.         }
  597.  
  598.         fp.close();
  599.  
  600.         texpic=flyengine->get_picture(skin);
  601.         if (texpic==-1)
  602.             {
  603.             if (strrchr(name,'\\'))
  604.                 strcpy(skin,strrchr(name,'\\')+1);
  605.             else if (strrchr(name,'/'))
  606.                 strcpy(skin,strrchr(name,'/')+1);
  607.             else strcpy(skin,name);
  608.             if (strrchr(skin,'.'))
  609.                 *strrchr(skin,'.')=0;
  610.             strcat(skin,".tga");
  611.             texpic=flyengine->get_picture(skin);
  612.             if (texpic==-1)
  613.                 {
  614.                 if (strrchr(skin,'.'))
  615.                     *strrchr(skin,'.')=0;
  616.                 strcat(skin,".jpg");
  617.                 texpic=flyengine->get_picture(skin);
  618.                 }
  619.             }
  620.  
  621.         vert=new vector[nv];
  622.         localfaces=new face[nf];
  623.         faces=new face *[nf];
  624.  
  625.         for( i=0;i<nf;i++ )
  626.             {
  627.             faces[i]=&localfaces[i];
  628.             localfaces[i].vert[0]=&vert[ao_face[i*3]];
  629.             localfaces[i].vert[1]=&vert[ao_face[i*3+1]];
  630.             localfaces[i].vert[2]=&vert[ao_face[i*3+2]];
  631.             localfaces[i].uv[0][0]=ao_uv[i*6];
  632.             localfaces[i].uv[0][1]=ao_uv[i*6+1];
  633.             localfaces[i].uv[1][0]=ao_uv[i*6+2];
  634.             localfaces[i].uv[1][1]=ao_uv[i*6+3];
  635.             localfaces[i].uv[2][0]=ao_uv[i*6+4];
  636.             localfaces[i].uv[2][1]=ao_uv[i*6+5];
  637.             localfaces[i].color.vec(1,1,1,1);
  638.             localfaces[i].lastdraw=0;
  639.             localfaces[i].normal.null();
  640.             }
  641.         
  642.         delete ao_face;
  643.         delete ao_uv;
  644.         ao_face=0;
  645.         ao_uv=0;
  646.  
  647.         set_key(0);
  648.         compute_normals(MESH_FACENORM|MESH_VERTNORM|MESH_BBOX|MESH_EDGES);
  649.         compute_bbox();
  650.  
  651.         return 1;
  652.         }
  653.     return 0;
  654. }
  655.  
  656. void anim_mesh::set_key(float key)
  657. {
  658.     if (key>=0.0f && key<=1.0f)
  659.     {
  660.     int i,j,k;
  661.     float s;
  662.     vector *v,*v0,*v1;
  663.     j=(int)(key*nframes);
  664.     if (j==nframes)
  665.         { j=0; key=0.0f; }
  666.     s=1.0f/nframes;
  667.     key=(key-j*s)/s;
  668.     v0=&ao_vert[j*nv];
  669.     if (j==nframes-1)
  670.         k=0;
  671.     else k=j+1;
  672.     v1=&ao_vert[k*nv];
  673.     v=vert;
  674.     for( i=0;i<nv;i++,v++,v0++,v1++ )
  675.         *v=*v0+(*v1-*v0)*key;
  676.  
  677.     bbox.min=ao_bbox[j*2]+(ao_bbox[k*2]-ao_bbox[j*2])*key;
  678.     bbox.max=ao_bbox[j*2+1]+(ao_bbox[k*2+1]-ao_bbox[j*2+1])*key;
  679. //    compute_normals(MESH_FACENORM|MESH_VERTNORM);
  680.     }
  681. }
  682.  
  683. void anim_mesh::set_key(int key)
  684. {
  685.     if (key>=0 && key<nframes)
  686.     {
  687.     memcpy(vert,&ao_vert[key*nv],sizeof(vector)*nv);
  688.  
  689.     bbox.min=ao_bbox[key*2];
  690.     bbox.max=ao_bbox[key*2+1];
  691.     compute_normals(MESH_FACENORM|MESH_VERTNORM);
  692.     }
  693. }
  694.  
  695. void mesh::implode(float mindist)
  696. {
  697.     if (vert==0) 
  698.         return;
  699.  
  700.     char *f=new char[nv];
  701.     memset(f,1,nv);
  702.  
  703.     int i,j,k,v;
  704.     for( i=0;i<nv;i++ )
  705.      if (f[i])
  706.      for( j=i+1;j<nv;j++ )
  707.         if (f[j])
  708.         if ((vert[i]-vert[j]).length()<mindist)
  709.         {
  710.         f[j]=0;
  711.         for( k=0;k<nf;k++ )
  712.          for( v=0;v<3;v++ )
  713.             if (localfaces[k].vert[v]==&vert[j])
  714.                 localfaces[k].vert[v]=&vert[i];
  715.         }
  716.  
  717.     for( i=0;i<nv;i++ )
  718.         if (f[i]==0)
  719.         {
  720.         for( k=0;k<nf;k++ )
  721.             for( v=0;v<3;v++ )
  722.                 if (localfaces[k].vert[v]-vert>i)
  723.                     localfaces[k].vert[v]=localfaces[k].vert[v]-1;
  724.         memcpy(&vert[i],&vert[i+1],sizeof(vector)*(nv-i-1));
  725.         memcpy(&f[i],&f[i+1],nv-i-1);
  726.         nv--;
  727.         i--;
  728.         }
  729.  
  730.     delete f;
  731. }
  732.  
  733.  
  734. void mesh::set_numverts(int nverts,int keep)
  735. {
  736.     vector *tmp=new vector[nverts];
  737.     if(keep)
  738.         if (nverts>=nv)
  739.             memcpy(tmp,vert,sizeof(vector)*nv);
  740.         else 
  741.             memcpy(tmp,vert,sizeof(vector)*nverts);
  742.     nv=nverts;
  743.     if (vert)
  744.         delete vert;
  745.     vert=tmp;
  746. }
  747.  
  748. void mesh::set_numfaces(int nfaces,int local,int keep)
  749. {
  750.     face **tmp1=new face *[nfaces];
  751.     if(keep)
  752.         if (nfaces>=nf)
  753.             memcpy(tmp1,faces,sizeof(face *)*nf);
  754.         else 
  755.             memcpy(tmp1,faces,sizeof(face *)*nfaces);
  756.     if (faces)
  757.         delete faces;
  758.     faces=tmp1;
  759.     if (local)
  760.     {
  761.         face *tmp2=new face[nfaces];
  762.         if(keep)
  763.             if (nfaces>=nf)
  764.                 memcpy(tmp2,localfaces,sizeof(face)*nf);
  765.             else 
  766.                 memcpy(tmp2,localfaces,sizeof(face)*nfaces);
  767.         if (localfaces)
  768.             delete localfaces;
  769.         localfaces=tmp2;
  770.     }
  771.     nf=nfaces;
  772. }
  773.